home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / clang / mcomm600.zip / ASYNC.DOC < prev    next >
Text File  |  1994-10-03  |  93KB  |  2,461 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.             ASYNCHRONOUS FUNCTIONS FOR MICROSOFT, TURBO, OR ZORTECH C
  7.  
  8.  
  9.             The LIB(s) on the included disk are libraries of serial
  10.          communications functions designed specifically for use with
  11.          Microsoft C, Turbo C / C++, and Zortech C / C++.  The regis-
  12.          tered version has LIBs for all memory models.  The shareware
  13.          version is small model only.
  14.  
  15.  
  16.                     --- Features of the library functions ---
  17.  
  18.             o Support for 16550 UART's FIFO mode of operation
  19.  
  20.             o Fully interrupt driven
  21.  
  22.             o Baud rates up to 115,200 baud
  23.  
  24.             o User defined transmit and receive ring buffer sizes.
  25.  
  26.             o Ring buffers may be in placed in FAR memory even in small
  27.               and medium model programs.
  28.  
  29.             o User defined port addresses, IRQ use, and interrupt vector
  30.               numbers.
  31.  
  32.             o Support for simultaneous operation of 4 ports.
  33.  
  34.             o Built in support for XON/XOFF and hardware flow control
  35.  
  36.             o Block transmit and receive functions
  37.  
  38.             o Receive buffer look ahead function
  39.  
  40.             o 100% assembler code for maximum speed
  41.  
  42.             o Totally compatible with Microsoft C, Turbo C, Zortech C,
  43.               and other C compilers that use standard Microsoft high
  44.               level language calling conventions.
  45.  
  46.  
  47.  
  48.          ---------------------------------------------------------------
  49.                 Mike Dumdei,  6 Holly Lane,  Texarkana TX  75503
  50.                    MCOMM5 (c) 1989-1994  All Rights Reserved
  51.          ---------------------------------------------------------------
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.                       REGISTRATION AND DISTRIBUTION POLICY
  59.  
  60.             MCOMM5, the various versions of Smalterm, the ANSI video
  61.          routines, and other miscellaneous functions contained in the
  62.          COMM_x libraries are distributed as shareware.  If you use
  63.          these functions regularly please register them.
  64.  
  65.             Two types of registration are available for MCOMM5.  The
  66.          first is $25 and includes assembled libraries for all memory
  67.          models.  The $25 registration does not include source code.
  68.          The second type of registration is $45 and includes libraries
  69.          and source code.  Previous versions were $25 for source code
  70.          and libraries.  If you send $25 and want source code based on
  71.          previous offers, you will receive a previous version of the
  72.          source.  Registered users of versions prior to version 5 may
  73.          upgrade their libraries for $3 or upgrade source code version
  74.          for $10.
  75.  
  76.             Considerable time and effort has gone into developing and
  77.          debugging these routines.  If you are not a registered user and
  78.          have obtained a copy of the registered version, please take
  79.          time now to register the software or delete it.  The copy you
  80.          have is a registered version if it contains libraries for any
  81.          memory model other than small model or if any of the ASM source
  82.          code is included.
  83.  
  84.             This software is provided as is without warranty as to its
  85.          fitness for a particular use or being free of errors.  I assume
  86.          no liability for any loss or damages you may incur through its
  87.          use.  I will, however, make every effort to correct any
  88.          software errors that may exist, and provide you with a working
  89.          version.
  90.  
  91.             I will continue to assist registered and non-registered
  92.          users whenever possible.  If you have any problems using these
  93.          routines or questions, I may be contacted at:
  94.  
  95.             North East Texas DataLink --  903 838-6713 (modem)
  96.                                           FIDO net:  1:3819/128
  97.  
  98.             Mike Dumdei               --  903 838-8307 (voice)
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.                                  GETTING STARTED
  106.  
  107.          All functions included in this library are listed on the fol-
  108.          lowing pages in alphabetical order.  The basic functions needed
  109.          to begin are: async_open, async_tx, async_rx, and async_close.
  110.  
  111.          Functions are also available to support XON/XOFF and hardware
  112.          flow control, the 16550 UART, block transmit and receive,
  113.          receive buffer look ahead, and several other features.
  114.  
  115.          All functions take a pointer to an ASYNC structure for one of
  116.          its arguments.  This structure is defined in COMM.H.  It
  117.          may be helpful to think of this structure as being similar to
  118.          the standard C library 'FILE *'.
  119.  
  120.          If you have been using versions of these routines prior to
  121.          version 5.00, there have been some changes made that will
  122.           require you to make some modifications to any existing code
  123.          before it can be used with the new libraries.  The main
  124.          differences are:
  125.  
  126.             > Async_open takes different parameters.  Also, instead
  127.               of the open function automatically allocating the ring
  128.               buffers for you, you provide the ring buffers.
  129.  
  130.             > All functions now take a pointer to an ASYNC structure
  131.               as the first argument rather than 0 (COM1) or 1 (COM2).
  132.  
  133.             > LITES is no longer supported.
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.                             NOTES ON 16550 FIFO MODE
  141.  
  142.             The 16550 UART is automatically detected and enabled when
  143.          async_open is called.  If, for some reason, you want to operate
  144.          a 16550 UART in non-FIFO mode, automatic detection and use can
  145.          be disabled.  See async_open for more information.
  146.  
  147.  
  148.                           --- Use of receiver FIFOs ---
  149.  
  150.             The receiver trigger level may be programmed for 1, 4, 8, or
  151.          14 bytes by the async_FIFOrxlvl function.  When a port is first
  152.          opened the trigger is set to 1 byte.  There are 3 reasons why I
  153.          chose to default to a 1 byte receive trigger level.
  154.  
  155.             1) While a higher trigger level results in less CPU
  156.                overhead, it also provides less overrun protection if the
  157.                CPU is slow to respond.  For example, with a 1 byte
  158.                trigger level the 16550 -- when it generates an interrupt
  159.                -- can hold 15 more characters in its FIFOs before the
  160.                CPU responds.  With a 14 byte trigger level it will only
  161.                have room for 2 more characters.
  162.  
  163.             2) The MCOMM interrupt functions completely empty the
  164.                receiver FIFOs every time an interrupt occurs.  If the
  165.                CPU is slow to respond, the interrupt handler will
  166.                process 2,3,4.. characters (whatever is in the FIFOs)
  167.                whenever it does get control so the data still gets
  168.                buffered if the CPU isn't able to keep up.
  169.  
  170.             3) Setting the trigger level at higher trigger levels when
  171.                displaying incoming data to the screen will result in a
  172.                jerky looking display, especially at low baud rates.
  173.                Again, this is because MCOMM empties the buffer
  174.                completely when it processes the interrupt.  With a
  175.                trigger level other than 1, data stacks up in the FIFOs
  176.                until the trigger level is reached.  When the interrupt
  177.                finally occurs, all the data in the FIFOs is pulled out
  178.                and made available to the higher level functions at
  179.                one time.  The result is your code sits for 4, 8, or 14
  180.                bytes (whatever the trigger is) and then puts those bytes
  181.                on the screen in a burst.  It looks rough at low baud
  182.                rates.  At 9600 baud and above you could probably get by
  183.                with a slightly higher trigger level.
  184.  
  185.             For best use of the receive FIFOs, stick with 1 byte trigger
  186.          level when displaying data to the screen.  If your application
  187.          does not display the data or uses a high baud rate, you may
  188.          want to experiment with setting it to either 4 or 8 bytes.
  189.  
  190.  
  191.                           --- Use of transmit FIFOs ---
  192.  
  193.             The MCOMM transmit interrupt handler takes a parameter (set
  194.          by async_FIFOtxlvl) that is the maximum number of bytes to load
  195.          into the transmit FIFOs at one time.  The default value for
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.                             NOTES ON 16550 FIFO MODE
  203.  
  204.          this parameter is 3 bytes.  The reason for not loading up the
  205.          FIFOs to maximum capacity (16 bytes) is flow control.  The
  206.          16550 UART will continue to transmit characters in its FIFOs
  207.          regardless of the state of CTS, DSR, or CD, or if an XOFF is
  208.          received.  It is totally up to the software to respond to
  209.          requests for flow control.  If the FIFOs are loaded with more
  210.          bytes than the receiver can handle when it invokes flow
  211.          control, the receiver gets overwritten.  There is a bit that
  212.          can be sent to the UART to flush the transmit FIFOs but then it
  213.          is impossible to tell what was flushed and what was sent.  The
  214.          solution is to not the load the FIFOs up so full.  If the
  215.          receiving device can handle more than 3 characters of overrun,
  216.          use a larger value.  If the application does not require flow
  217.          control, you can use a 16 byte level with no problems.
  218.  
  219.             Another factor to consider concerning the transmit FIFO byte
  220.          level is that (from the NS Data Communications/LAN/UART
  221.          Handbook) the transmit FIFO empty indication will be delayed by
  222.          1 character time minus the last stop bit until there are at
  223.          least 2 bytes in the transmit FIFOs simultaneously for the
  224.          current transmit operation.  After the 2 byte requirement is
  225.          met the transmit interrupt occurs immediately when the transmit
  226.          FIFOs empty.  Using a value of 3 or above (1 byte for the
  227.          transmit shift register and 2 for the FIFO registers)
  228.          guarantees the interrupt delay is deactivated.  Once the '2
  229.          bytes in the FIFOs' requirement is met, the transmit byte level
  230.          can be reduced if necessary.
  231.  
  232.  
  233.                   --- Problems with Western Digital 16550s ---
  234.  
  235.          The following problems DO NOT apply to the National Semicon-
  236.          ductor version of the 16550.  Neither are they unique to MCOMM.
  237.  
  238.          Western Digital 16550 UARTs have two problems you should be
  239.          aware of if your application will be ran on system that uses
  240.          this chip.
  241.  
  242.          The first of these only shows up under the following
  243.          conditions:
  244.  
  245.             1) The UART is in FIFO mode.
  246.             2) A low baud rate is being used.
  247.             3) The transmitter is initially empty.
  248.             4) A block of data longer than 16 to 18 bytes (depth of the
  249.                FIFOs plus 1 or 2 for what gets out while the FIFOs are
  250.                being filled up) is sent to the chip.
  251.  
  252.          Under these conditions the WD16550 UART will momentarily fail
  253.          to recognize the FIFOs are full and continue to generate
  254.          transmit interrupts.  It also fails to reset the 'Transmit Hold
  255.          Register Empty' bit making it impossible for the software to
  256.          detect a full FIFO condition.  The result is the software keeps
  257.          sending data to the chip, overrunning the FIFOs.  What you will
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.                             NOTES ON 16550 FIFO MODE
  265.  
  266.          see is, the first 16 to 18 bytes transmitted correctly, a
  267.          missing block of data, and then the remainder of the block also
  268.          correct.  This can be verified by trying to send blocks of data
  269.          through this chip (WD16550) at a low baud rate with any
  270.          software that enables the FIFOs.  How low of a baud rate is low
  271.          enough to cause the problem depends on the particular chip and
  272.          how fast the CPU and software can supply data to the chip.
  273.          With MCOMM, a 20 MHZ 386, and the TxByteCnt at the default
  274.          level of 3, the chip I was testing would not work in FIFO mode
  275.          below 9600 baud.  On the same system using different software,
  276.          it worked as low as 4800 baud.  On a 12 MHZ 286, MCOMM would
  277.          work at 4800 and above while the other software worked at 2400
  278.          and above.
  279.  
  280.          For publicly distributed applications, I recommend you do one
  281.          or more of the following:
  282.  
  283.             1) Provide an option in your program to allow the end user
  284.                to operate a 16550 with the FIFOs disabled.  When the
  285.                FIFOs are disabled, all baud rates work.  ORing the
  286.                'vctrnbr' parameter of async_open with 0x4000 will force
  287.                FIFO mode off.
  288.             2) Provide an option in your program to allow setting the
  289.                TxByteCnt level (async_FIFOtxlvl) to a lower value.  This
  290.                will help slightly.
  291.  
  292.             3) Put a flag in your program the end user can set to let
  293.                you know you are dealing with a WD16550.
  294.  
  295.             4) State your application does not support the Western
  296.                Digital version of the 16550 at low baud rates.
  297.  
  298.  
  299.          The second problem with the WD16550 is that if the 'Clear to
  300.          Send' signal is not connected it can, under some conditions,
  301.          cause the 'Delta Clear to Send' bit in the Modem Status
  302.          Register to become set and it will not reset.  I did not
  303.          research the problem enough to know if the 'locked bit' only
  304.          occurs when MSR interrupts are enabled, whether other floating
  305.          MSR input signals can cause the same problem, if all WD16550's
  306.          have the problem, or that is unique to the Western Digital chip
  307.          (considering the FIFO overrun problem, I assume it is unique).
  308.  
  309.          With a properly functioning UART, reading the MSR register will
  310.          reset all the 'delta bits' and clear any interrupts.  With the
  311.          chip I had, I tried everything I could think of to clear the
  312.          interrupt and nothing worked except the ON/OFF switch.  I tried
  313.          clearing interrupts and reading the MSR multiple times checking
  314.          to see if the bit reset with interrupts off (it didn't),
  315.          disabling Modem Status interrupts via the Interrupt Enable
  316.          Register and then reading the MSR register (didn't work), FIFO
  317.          mode on / FIFO mode off (no difference), keyboard reboot of the
  318.          computer (didn't fix it), shut the computer off and turn it
  319.          back on (that fixed it).
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.                             NOTES ON 16550 FIFO MODE
  327.  
  328.          After encountering this problem and having the system lock up,
  329.          I added code to MCOMM's interrupt driver so that it would quit
  330.          trying to clear an interrupt after 1000 attempts.  It then sets
  331.          a new port structure member 'IERVal' to zero as an indicator
  332.          the port is locked up.  Normally 'IERVal' will be set to the
  333.          current value of the Interrupt Enable Register.  If you try to
  334.          open a port that is in a stuck interrupt condition, async_open
  335.          now returns R_UARTERR.  In addition, options were added to open
  336.          a port without enabling Modem Status interrupts or Line Status
  337.          interrupts or both.  ORing the 'vctrnbr' parameter of async_open
  338.          with 0x2000 disables MSR interrupts.  ORing with 0x1000
  339.          disables LSR interrupts.  So far I have encountered no reason
  340.          for disabling LSR interrupts.  Disabling MSR interrupts
  341.          prevents the lock up problem but has the side effect of causing
  342.          all functions and variables that use Modem Status signals to be
  343.          invalid.  This includes hardware handshake and carrier detect.
  344.  
  345.          I have probably over emphasized the Modem Status lock up
  346.          problem and my personal opinion is that it is not that serious.
  347.          I considered totally disregarding it since it has a simple
  348.          solution and that is to connect all Modem Status input signals
  349.          to some driving signal (wire the RS232 cable right).  Unused
  350.          signals can be connected to a driving signal on the computer
  351.          end if necessary.  Also it may be isolated to one defective
  352.          chip.  I tested two WD16550s and the problem only showed up on
  353.          one of them during my testing.  Because the computer totally
  354.          locked up when this happened though, I decided to go ahead and
  355.          program for the possibility.  At least control of the computer
  356.          is regained and you can tell the user he needs a properly wired
  357.          RS232 cable or his UART is broke and then exit gracefully.
  358.          This will probably show up very very rarely so don't be too
  359.          concerned about it.  In closing, I would like to point out
  360.          again that these problems are a fault of the WD16550 and are
  361.          not unique to MCOMM.
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.          async_16550
  369.          ---------------------------------------------------------------
  370.  
  371.          Purpose: Check if 16550 UART was detected in system.
  372.  
  373.          Format:  int async_16550(port);
  374.                    ASYNC *port;       Pointer to ASYNC structure
  375.  
  376.          Example:
  377.  
  378.                   ASYNC *port;
  379.                   int is_16550;
  380.  
  381.                   is_16550 = async_16550(port);
  382.  
  383.          Returns: Returns zero if a 16550 is not in the system or the
  384.                   'ignore 16550 bit' was set when async_open was called.
  385.                   Returns NZ if a 16550 was found.  Async_open must be
  386.                   called before this function is valid.  If a 16550 is
  387.                   found, it will be placed in the FIFO mode of operation
  388.                   by async_open unless '16550 detect' was overridden or
  389.                   the force FIFOs off option was selected.
  390.  
  391.          Remarks: This function is implemented as a macro.
  392.  
  393.                   See async_open.
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.          async_breakrxd
  401.          ---------------------------------------------------------------
  402.  
  403.          Purpose: Checks if a break signal has been received.
  404.  
  405.          Format:  int async_breakrxd(port);
  406.                    ASYNC *port;       Pointer to ASYNC structure
  407.  
  408.          Example:
  409.  
  410.                   ASYNC *port;
  411.                   int break_status;
  412.  
  413.                   break_status = async_breakrxd(port);
  414.  
  415.  
  416.          Returns: If a break signal has been received the function
  417.                   returns a non-zero value.  If a break has not been
  418.                   detected, zero is returned.
  419.  
  420.          Remarks: Once a break signal has been detected, this function
  421.                   continually returns non-zero values until async_reset
  422.                   is called.  If a break is received, a line status
  423.                   register interrupt is generated.  The interrupt
  424.                   handler sets a bit in the Stat1 port structure member.
  425.                   The async_breakrxd function is a macro that checks the
  426.                   status of this bit.
  427.  
  428.                   See also async_reset, async_rx, async_stat,
  429.                   async_sndbrk.
  430.  
  431.  
  432.  
  433.  
  434.  
  435.  
  436.          async_carrier
  437.          ---------------------------------------------------------------
  438.  
  439.          Purpose: Check for the presence of a carrier.
  440.  
  441.          Format:  int async_carrier(port);
  442.                    ASYNC *port;       Pointer to ASYNC structure
  443.  
  444.          Example:
  445.  
  446.                   ASYNC *port;
  447.                   int carrier_status;
  448.  
  449.                   carrier_status = async_carrier(port);
  450.  
  451.  
  452.          Returns: A non-zero value is returned if a carrier is present.
  453.                   If the carrier detect line is LOW, zero is returned.
  454.  
  455.          Remarks: This function is implemented as a macro.  See also
  456.                   async_rx and async_stat.
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.          async_close
  464.          ---------------------------------------------------------------
  465.  
  466.          Purpose: Closes a port opened by async_open.
  467.  
  468.          Format:  int async_close(port);
  469.                    ASYNC *port;    Pointer to ASYNC structure
  470.  
  471.          Example:
  472.  
  473.                   ASYNC port;
  474.                   async_close(&port);
  475.  
  476.          Returns: No return value
  477.  
  478.          Remarks: Do not attempt to close an unopened port.  Some
  479.                   minimal checking is done internally by async_close in
  480.                   an attempt to detect whether or not the specified port
  481.                   is actually opened.  If an unopened port makes it past
  482.                   those checks and the main close routine is entered,
  483.                   the system may lock up (immediately, 2 hours later, or
  484.                   never).  When a port is closed the UART registers,
  485.                   interrupt controller mask, and interrupt vectors are
  486.                   restored to the value they had when async_open was
  487.                   called.  It is possible to close the port and leave
  488.                   various signals (DTR for one) in the state you desire
  489.                   rather than in their initial state.  See async_dtr and
  490.                   async_rts for some examples on how to do this.
  491.  
  492.                   The B_ORGFIFO bit in the ASYNC 'Stat3' structure
  493.                   member is used by async_close to return the 16550 --
  494.                   if present -- to the mode it was in when async_open
  495.                   was called.  FIFOs may be 'forced' to remain enabled
  496.                   or 'forced' to be disabled when closing the port by
  497.                   first setting or resetting this bit.  Ex:
  498.  
  499.                     Force off:    port->Stat3 &= ~B_ORGFIFO;
  500.                                   async_close(port);
  501.  
  502.                     Force on:     port->Stat3 |= B_ORGFIFO;
  503.                                   async_close(port);
  504.  
  505.  
  506.  
  507.  
  508.  
  509.  
  510.          async_cts
  511.          ---------------------------------------------------------------
  512.  
  513.          Purpose: Check status of the Clear to Send signal.
  514.  
  515.          Format:  int async_cts(port);
  516.                    ASYNC *port;       Pointer to ASYNC structure
  517.  
  518.          Example:
  519.  
  520.                   ASYNC *port;
  521.                   int cts_status;
  522.  
  523.                   cts_status = async_cts(port);
  524.  
  525.          Returns: Returns zero if Clear To Send is LOW.  If CTS is HIGH,
  526.                   a non-zero value is returned.
  527.  
  528.          Remarks: This function is implemented as a macro.
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.          async_dsr
  536.          ---------------------------------------------------------------
  537.  
  538.          Purpose: Check status of the Data Set Ready signal.
  539.  
  540.          Format:  int async_dsr(port);
  541.                    ASYNC *port;       Pointer to ASYNC structure
  542.  
  543.          Example:
  544.  
  545.                   ASYNC *port;
  546.                   int dsr_status;
  547.  
  548.                   dsr_status = async_dsr(port);
  549.  
  550.          Returns: Returns zero if Data Set Ready is LOW.  If DSR is
  551.                   HIGH, a non-zero value is returned.
  552.  
  553.          Remarks: This function is implemented as a macro.
  554.  
  555.  
  556.  
  557.  
  558.  
  559.  
  560.          async_dtr
  561.          ---------------------------------------------------------------
  562.  
  563.          Purpose: Set or reset the Data Terminal Ready signal.
  564.  
  565.          Format:  void async_dtr(port, DTRflag);
  566.                    ASYNC *port;       Pointer to ASYNC structure
  567.                    int DTRflag;       Set/Reset DTR flag
  568.  
  569.          Example:
  570.  
  571.                   ASYNC *port;
  572.  
  573.                   if (WantToDropDTR)
  574.                       async_dtr(port, 0);
  575.                   else if (WantDTRhigh)
  576.                       async_dtr(port, 1);
  577.  
  578.  
  579.          Returns: No return value
  580.  
  581.          Remarks: This signal is set HIGH when a port is first opened.
  582.                   When the port is closed, it is restored to the cond-
  583.                   ition it was in when the port was opened.  To force
  584.                   DTR low when a port is closed, regardless of its state
  585.                   when the port was opened, AND the port member, OldMCR,
  586.                   with NOT B_DTR.  To force DTR to remain high when the
  587.                   port is closed, OR OldMCR with B_DTR.
  588.  
  589.                     Force low:    port->OldMCR &= ~B_DTR;
  590.                                   async_close(port);
  591.  
  592.                     Force high:   port->OldMCR |= B_DTR;
  593.                                   async_close(port);
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.          async_FIFOrxlvl  <5.20 addition>
  601.          ---------------------------------------------------------------
  602.  
  603.          Purpose: Set the 16550 UART's receive trigger level.
  604.  
  605.          Format:  void async_FIFOrxlvl(port, trigger_lvl);
  606.                    ASYNC *port;       Pointer to ASYNC structure
  607.                    int trigger_lvl;   Rx FIFO interrupt trigger level
  608.  
  609.          Example:
  610.  
  611.                   ASYNC *port;
  612.  
  613.                    /* set the receiver trigger level to 8 bytes */
  614.                   async_FIFOrxlvl(port, 8);
  615.  
  616.          Returns: No return value
  617.  
  618.          Remarks: Valid values for 'trigger_lvl' are 1, 4, 8, and 14
  619.                   bytes.  When a port with a 16550 UART is first opened,
  620.                   the trigger level is set to 1 byte.  See the
  621.                   discussion on 'Use of receiver FIFOs' at the beginning
  622.                   of this document.  This function has no effect if the
  623.                   FIFOs were not enabled when async_open was called.
  624.  
  625.  
  626.  
  627.  
  628.  
  629.  
  630.          async_FIFOtxlvl  <5.20 addition>
  631.          ---------------------------------------------------------------
  632.  
  633.          Purpose: Set the number of bytes loaded into the 16550 UART's
  634.                   transmit FIFOs when a transmit interrupt occurs.
  635.  
  636.          Format:  void async_FIFOtxlvl(port, bytes);
  637.                    ASYNC *port;       Pointer to ASYNC structure
  638.                    int bytes;         # of bytes to load into tx FIFOs
  639.  
  640.          Example:
  641.  
  642.                   ASYNC *port;
  643.  
  644.                    /* set the transmit FIFO byte level to 16 bytes */
  645.                   async_FIFOrxlvl(port, 16);
  646.  
  647.          Returns: No return value
  648.  
  649.          Remarks: Valid values for 'bytes' are 1 through 16 bytes.  When
  650.                   a port with a 16550 UART is first opened, the transmit
  651.                   level byte count is set to 3 bytes.  See the
  652.                   discussion on 'Use of transmit FIFOs' at the beginning
  653.                   of this document.  This function has no effect if the
  654.                   FIFOs were not enabled when async_open was called.
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.          async_ignerr
  662.          ---------------------------------------------------------------
  663.  
  664.          Purpose: Set or reset 'ignore characters with errors' bit
  665.  
  666.          Format:  void async_ignerr(port, flag);
  667.                    ASYNC *port;       Pointer to ASYNC structure
  668.                    int flag;          Set/Reset flag
  669.  
  670.          Example:
  671.  
  672.                   ASYNC *port;
  673.  
  674.                   if (WantToDiscardErrChars)
  675.                       async_ignerr(port, 1);
  676.                   else if (WantToKeepErrChars)
  677.                       async_ignerr(port, 0);
  678.  
  679.  
  680.          Returns: No return value
  681.  
  682.          Remarks: This function sets the bit that determines what hap-
  683.                   pens to received characters that have parity or fram-
  684.                   ing errors.  If the function is called with the flag
  685.                   set to one, incoming characters that have framing or
  686.                   parity errors are discarded -- they do not get put
  687.                   into the receive ring buffer.  If the flag is 0, char-
  688.                   acters with errors are not ignored, they are put into
  689.                   the ring buffer.  The error bits in Stat1 that reflect
  690.                   these error conditions are set regardless of the
  691.                   setting of the discard flag.  When a port is first
  692.                   opened, the flag is set to 0.  This function is imple-
  693.                   mented as a macro.
  694.  
  695.                   See also async_stat.
  696.  
  697.  
  698.  
  699.  
  700.  
  701.  
  702.          async_msr
  703.          ---------------------------------------------------------------
  704.  
  705.          Purpose: Get the contents of the Modem Status Register.
  706.  
  707.          Format:  int async_msr(port);
  708.                    ASYNC *port;       Pointer to ASYNC structure
  709.  
  710.          Example:
  711.  
  712.                   ASYNC *port;
  713.                   int MSRcontents;
  714.  
  715.                   MSRcontents = async_msr(port);
  716.  
  717.  
  718.          Returns: The contents of the Modem Status Register.
  719.  
  720.          Remarks: This function is a macro that returns the port struc-
  721.                   ture member, MSRVal.  This value is initialized when a
  722.                   port is first opened and then updated any time a modem
  723.                   status interrupt occurs.  The reason the MSR is not
  724.                   read directly is to avoid inadvertently intercepting a
  725.                   pending MSR interrupt.  All bits returned except for
  726.                   the delta bits reflect the true current status.
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733.          async_msrflow  <5.50 modified>
  734.          ---------------------------------------------------------------
  735.  
  736.          Purpose: Enables or disables hardware flow control.
  737.  
  738.          Format:  void async_msrflow(port, flowmask);
  739.                    ASYNC *port;       Pointer to ASYNC structure
  740.                    int flowmask;      Bit mapped flow control mask
  741.  
  742.          Example:
  743.  
  744.                   ASYNC *port;
  745.  
  746.                   if (enable_RTS_CTS_handshake)
  747.                       async_msrflow(port, B_CTS);
  748.                   else if (disable_handshake)
  749.                       async_msrflow(port, 0);
  750.  
  751.          Returns: No return value
  752.  
  753.          Remarks: The flow mask is a bit mapped value of the signal that
  754.                   is monitored by the receiver when performing flow
  755.                   control.  Bits that may be monitored are B_CTS, B_DSR,
  756.                   and B_CD.  This provides capability for RTS/CTS hand-
  757.                   shake, DTR/DSR handshake, and handshaking with the
  758.                   carrier detect line.  To monitor multiple signals, OR
  759.                   the bits together.  Both hardware flow control and
  760.                   XON/XOFF flow control may be enabled at the same time.
  761.  
  762.                   Beginning with version 5.50, ORing B_RTS into the
  763.                   'flowmask' parameter, will cause the RTS signal to be
  764.                   driven low whenever the receive buffer exceeds the
  765.                   XoffTrip point.  RTS will automatically return to its
  766.                   normal condition when the receive buffer empties to a
  767.                   point below the XonTrip level.  Both XOFF/XON and RTS
  768.                   flow control share the same trip point variable but
  769.                   may be activated separately or together.  Do not get
  770.                   RTS and CTS confused.  Use CTS to keep the computer
  771.                   from overrunning a device (e.g. sending to a modem
  772.                   with a locked baud rate).  Use RTS to keep from
  773.                   getting ran over by a device (receiving from a high
  774.                   speed modem using a slow computer).
  775.  
  776.                   See async_xflow.
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.          async_open  <5.40 modified -- see Remarks at end of function>
  784.          ---------------------------------------------------------------
  785.  
  786.          Purpose: Initializes the hardware, interrupt vector, and ASYNC
  787.                   port structure for interrupt driven operation.
  788.  
  789.          Format:
  790.                   int async_open(port, base, irqmask, vctrnbr, params);
  791.                    ASYNC *port;   Pointer to ASYNC structure
  792.                    int base;      Base port address of UART chip
  793.                    int irqmask;   8259 mask value for selected IRQ line
  794.                                    (1 << IRQnumber) for IRQs 0-7  or
  795.                                    (1 << (IRQnumber - 8)) for IRQs 8-15
  796.                    int vctrnbr;   Number of selected interrupt vector
  797.                                    (8 + IRQnumber) for IRQs 0-7
  798.                                    (104 + IRQnumber) for IRQs 8-15
  799.                    char *params;  Baud, parity, data, & stop bits in
  800.                                    string format
  801.  
  802.          Entry:   Before calling this function you must allocate ring
  803.                   buffer memory and pre-initialize the following ASYNC
  804.                   structure members:
  805.  
  806.                    RxSize : the size that you want the receive ring
  807.                       buffer to be.  The memory allocated or set aside
  808.                       for the receive ring buffer must be contiguous
  809.                       with the memory used for the transmit  ring
  810.                       buffer.  In most cases (RxSize + TxSize) bytes
  811.                       will be allocated using some form of malloc.
  812.                       A function to do this is included in the examples.
  813.                       The combined size of RxSize + TxSize can not
  814.                       exceed 32K - 1.
  815.                    TxSize : the size of the transmit buffer in bytes.
  816.                       As stated above, the transmit and receive buffers
  817.                       for each individual port must be allocated as one
  818.                       contiguous block.
  819.                    RingSeg: the segment address of the memory allocated
  820.                       for the receive and transmit buffers.  FAR memory
  821.                       can be used for the receive and transmit buffers
  822.                       by using your compiler library's version of FAR
  823.                       malloc and putting the segment portion (high 16
  824.                       bits) of the returned memory pointer in RingSeg.
  825.                       If you are using a NEAR data model program and
  826.                       want NEAR ring buffers, set RingSeg equal to 0.
  827.                       With RingSeg set to zero, the open function will
  828.                       use the DS segment register for RingSeg.  Using
  829.                       FAR ring buffers causes no loss of performance.
  830.                   RingOfst: the offset address of the memory allocated
  831.                       for the receive and transmit buffers.  This value,
  832.                       in conjunction with the RxSize and TxSize vari-
  833.                       ables, is used to set up the receive and transmit
  834.                       ring buffers.
  835.  
  836.  
  837.  
  838.  
  839.  
  840.  
  841.          async_open
  842.          ---------------------------------------------------------------
  843.  
  844.                   THE FOLLOWING FUNCTION IS INCLUDED WITH MCOMM5 AND IS
  845.                   RECOMMENDED FOR ALLOCATING RING BUFFER MEMORY AND
  846.                   INITIALIZING THE ABOVE VARIABLES.
  847.  
  848.          #if defined (__TURBOC__)         /* Turbo C */
  849.             #include <alloc.h>
  850.             #define _fmalloc farmalloc
  851.          #elif defined (__ZTC__)          /* Zortech C */
  852.             #include <dos.h>
  853.             #include <stdlib.h>
  854.             #define _fmalloc farmalloc
  855.          #else                            /* Microsoft C */
  856.             #include <malloc.h>
  857.          #endif
  858.  
  859.          int AllocRingBuffer(
  860.           ASYNC *port,                  /* pointer to port structure */
  861.           int rxsize,      /* number bytes to use for receive buffer */
  862.           int txsize,     /* number bytes to use for transmit buffer */
  863.           int useFARmem)    /* flag set if using FAR mem for buffers */
  864.          {
  865.             unsigned long memptr;
  866.             int memsize;
  867.  
  868.             memsize = rxsize + txsize;
  869.  
  870.             if (useFARmem || sizeof(char *) == 4)/* if FAR Ring bufs */
  871.                memptr = (unsigned long)_fmalloc(memsize);
  872.             else                  /* if Ring buffers use NEAR memory */
  873.                memptr = (unsigned long)(unsigned int)malloc(memsize);
  874.  
  875.              /* pre-initialize 4 required structure members */
  876.             port->RxSize = rxsize;            /* receive buffer size */
  877.             port->TxSize = txsize;           /* transmit buffer size */
  878.             port->RingSeg = (int)(memptr >> 16);          /* SEG adr */
  879.             port->RingOfst = (int)memptr;            /* OFST address */
  880.             if (memptr == 0L)
  881.                return 0;          /* return 0 if no memory available */
  882.             return 1;                   /* return 1, had some memory */
  883.          }
  884.  
  885.  
  886.  
  887.  
  888.  
  889.  
  890.          async_open
  891.          ---------------------------------------------------------------
  892.  
  893.          Example 1:
  894.  
  895.             /*
  896.                Open COM1 at 2400,N,8,1 using FAR ring buffers. COM1 is
  897.                defined in COMM.H as:  0x3f8, 0x10, 12.  It is not
  898.                necessary to check the return value of AllocRingBuffer
  899.                since async_open will return R_NOMEM if the memory
  900.                allocation function fails.
  901.             */
  902.  
  903.             #include "comm.h"
  904.  
  905.             ASYNC port;
  906.             int rcode;
  907.  
  908.             AllocRingBuffer(&port, 24000, 8000, 1);
  909.  
  910.             rcode = async_open(&port, COM1, "2400N81");
  911.           /**  or
  912.             rcode = async_open(&port, 0x3f8, 0x10, 12, "2400N81");
  913.            **  or
  914.             rcode = async_open(&port, 0x3f8, IRQ4, VCTR4, "2400N81");
  915.            **/
  916.  
  917.             if (rcode != R_OK)
  918.             {
  919.                 printf("\nAsync_open failed, exit code = %d", rcode);
  920.                 exit(rcode);
  921.             }
  922.  
  923.  
  924.  
  925.  
  926.  
  927.  
  928.          async_open
  929.          ---------------------------------------------------------------
  930.  
  931.          Example 2:
  932.  
  933.             /*
  934.                Open a port located at 0x2e0 that uses IRQ3.  In this
  935.                case NEAR ring buffers are specified and the memory for
  936.                the port structure is obtained using malloc.  See the
  937.                AllocRingBuffer function described previously.
  938.             */
  939.  
  940.             #include "comm.h"
  941.  
  942.             ASYNC *port;
  943.             int rcode;
  944.  
  945.             if ((port = (ASYNC *)malloc(sizeof ASYNC)) == NULL)
  946.             {
  947.                 printf("\nNot enough memory");
  948.                 exit(R_NOMEM);
  949.             }
  950.  
  951.             AllocRingBuffer(port, 4096, 1200, 0);
  952.  
  953.             rcode = async_open(port, 0x2e0, IRQ3, VCTR3, "115200E71");
  954.  
  955.             if (rcode != R_OK)
  956.             {
  957.                 printf("\nAsync_open failed, exit code = %d", rcode);
  958.                 exit(rcode);
  959.             }
  960.  
  961.  
  962.  
  963.  
  964.  
  965.  
  966.          async_open
  967.          ---------------------------------------------------------------
  968.  
  969.          Example 3:
  970.  
  971.             /*
  972.                Open both COM1 and COM2 at the same time.  You can open
  973.                four ports at once as long as they don't share the same
  974.                port addresses, IRQ lines, or interrupt vectors.
  975.             */
  976.  
  977.             #include "comm.h"
  978.  
  979.             ASYNC ports[2], *port[2];
  980.             int rcode;
  981.  
  982.             port[0] = &ports[0], port[1] = &ports[1];
  983.  
  984.             AllocRingBuffer(port[0], 10240, 10240, 1);
  985.             rcode = async_open(port[0], COM1, "9600N81");
  986.             if (rcode != R_OK)
  987.             {
  988.                 printf("\nAsync_open failed, exit code = %d", rcode);
  989.                 exit(rcode);
  990.             }
  991.  
  992.             AllocRingBuffer(port[1], 10240, 10240, 1);
  993.             rcode = async_open(port[1], COM2, "1200E71");
  994.             if (rcode != R_OK)
  995.             {
  996.                 printf("\nAsync_open failed, exit code = %d", rcode);
  997.                 exit(rcode);
  998.             }
  999.  
  1000.  
  1001.  
  1002.  
  1003.  
  1004.  
  1005.          async_open
  1006.          ---------------------------------------------------------------
  1007.  
  1008.          Example 4:
  1009.  
  1010.             /*
  1011.                Open COM1 using its current baud, parity, data, and
  1012.                stop bit settings.  The port structure member, BPDSstr,
  1013.                will reflect those settings after calling async_open.
  1014.             */
  1015.  
  1016.             #include "comm.h"
  1017.  
  1018.             ASYNC *port;
  1019.             int rcode;
  1020.  
  1021.              /* alloc port structure & ring buffer memory */
  1022.             port = malloc(sizeof(ASYNC));
  1023.             AllocRingBuffer(port, 4096, 2048, 1);
  1024.  
  1025.              /* empty parameter string causes port to be opened at
  1026.                 its current settings  */
  1027.             rcode = async_open(port, COM1, "");
  1028.  
  1029.             if (rcode != R_OK)
  1030.             {
  1031.                 printf("\nAsync_open failed, exit code = %d", rcode);
  1032.                 exit(rcode);
  1033.             }
  1034.  
  1035.             printf(
  1036.              "\nBaud, parity, data, stop bits = %s\n", port->BPDSstr);
  1037.  
  1038.  
  1039.  
  1040.  
  1041.  
  1042.  
  1043.          async_open
  1044.          ---------------------------------------------------------------
  1045.  
  1046.          Returns:
  1047.  
  1048.                   R_OK (0) - the port was opened with no errors.
  1049.  
  1050.                   R_NOMEM - a NULL pointer was passed as the address
  1051.                       of the ring buffers.  Probable causes are either
  1052.                       failing to initialize the port structure ring
  1053.                       buffer variables or assigning the RingSeg and
  1054.                       RingOfst structure a NULL pointer.  This could
  1055.                       occur if you use the AllocRingBuffer function or
  1056.                       something similar and the call to malloc fails.
  1057.  
  1058.                   R_BAUDERR - the passed baud rate in the BPDS string
  1059.                       was invalid.  Some possible reasons for this error
  1060.                       are leading spaces in the parameter string or use
  1061.                       of commas.  "115200N81" is correct. " 115200N81"
  1062.                       and "115,200N81" are both incorrect.
  1063.  
  1064.                   R_PARITYERR - an invalid character was found in the
  1065.                       parameter string where the parity should have
  1066.                       been.  Commas or spaces in the parameter string
  1067.                       are possible causes.  Valid parity settings are N
  1068.                       - none, E - even, or O - odd.  See R_BAUDERR.
  1069.  
  1070.                   R_DTABITERR - an invalid number of data bits was spec-
  1071.                       ified.  Only settings of 7 or 8 are supported.
  1072.  
  1073.                   R_STPBITERR - an invalid number of stop bits was spec-
  1074.                       ified.  Stop bits must be set to either 1 or 2.
  1075.  
  1076.                   R_IRQUSED - an attempt was made to open two ports that
  1077.                       use the same IRQ line.
  1078.  
  1079.                   R_VCTRUSED - an attempt was made to open two ports
  1080.                       that use the same interrupt vector.
  1081.  
  1082.                   R_NOPORT - an attempt was made to open more than four
  1083.                       simultaneous ports.
  1084.  
  1085.                   R_PORTUSED - an attempt was made to open two ports
  1086.                       that have the same I/O address.
  1087.  
  1088.                   R_UARTERR - an attempt was made to open a port that is
  1089.                       stuck in an interrupt condition (see the notes on
  1090.                       problems with the WD16550 at the beginning of this
  1091.                       documentation ).
  1092.  
  1093.  
  1094.  
  1095.  
  1096.  
  1097.  
  1098.          async_open
  1099.          ---------------------------------------------------------------
  1100.  
  1101.          Remarks (16550 support):
  1102.  
  1103.                   This function now automatically detects the presence
  1104.                   of a 16550 UART and enables FIFO operation if one is
  1105.                   detected.  By ORing either 0x8000 or 0x4000 with the
  1106.                   'vctrnbr' argument, you can change the default of auto-
  1107.                   enabling FIFO mode.  If 0x8000 is ORed with the
  1108.                   'vctrnbr' argument (ex: 0x8000|vctrnbr), no attempt is
  1109.                   made to detect a 16550 and no changes are made to the
  1110.                   mode of operation of the 16550 if one is present.  If
  1111.                   this bit is set, none of the functions or bits
  1112.                   relating to the 16550 UART will be valid.  If 0x4000
  1113.                   is ORed with the 'vctrnbr', the 16550 will be forced
  1114.                   into non-FIFO mode.
  1115.  
  1116.                   ORing 0x2000 with the 'vctrnbr' parameter will open the
  1117.                   port with MSR interrupts disabled.  ORing the 'vctrnbr'
  1118.                   parameter with 0x1000 will open the port with LSR
  1119.                   interrupts disabled.  See the notes on the WD16550 at
  1120.                   the beginning of this documentation for why this may
  1121.                   be desired and the side effects of opening a port with
  1122.                   MSR interrupts disabled.
  1123.  
  1124.                   When async_open is called, the FIFOs are momentarily
  1125.                   disabled and then re-enabled with the receive trigger
  1126.                   level set to 1 byte.  In versions of MCOMM prior to
  1127.                   5.40, the FIFOs were not reset if they were already
  1128.                   on.  Resetting the FIFOs was added to correct
  1129.                   occasional rare problems with the port not opening.
  1130.  
  1131.                     /* detect 16550, enable FIFOs if present */
  1132.                   async_open(PortPtr, 0x3f8, IRQ, Vector, Params);
  1133.  
  1134.                    /* do not attempt to detect 16550 */
  1135.                   async_open(PortPtr, 0x3f8, IRQ, 0x8000|Vctr, Params);
  1136.  
  1137.                    /* detect 16550, disable FIFOs if present */
  1138.                   async_open(PortPtr, 0x3f8, IRQ, 0x4000|Vctr, Params);
  1139.  
  1140.                    /* open port, disable MSR interrupts */
  1141.                   async_open(PortPtr, 0x3f8, IRQ, 0x2000|Vctr, Params);
  1142.  
  1143.                    /* open port, disable MSR interrupts and FIFOs */
  1144.                   async_open(PortPtr, 0x3f8, IRQ, 0x6000|Vctr, Params);
  1145.  
  1146.  
  1147.  
  1148.  
  1149.  
  1150.  
  1151.          async_open
  1152.          ---------------------------------------------------------------
  1153.  
  1154.          Remarks (versions previous to 5.00):
  1155.  
  1156.                   There are some major differences in the async_open
  1157.                   function in MCOMM5 and previous versions of the rou-
  1158.                   tines.  The two most major ones are that the parame-
  1159.                   ters passed to the function are different and it is
  1160.                   now necessary to allocate the memory for the ring
  1161.                   buffers before calling the function.  To make things
  1162.                   simpler, COM1 and COM2 are defined in COMM.H and the
  1163.                   function, AllocRingBuffer, is provided.  The COM1 and
  1164.                   COM2 definitions satisfy the requirements for the 2nd,
  1165.                   3rd, and 4th parameters required by the function.  For
  1166.                   ports other than the standard COM1 and COM2, it is
  1167.                   necessary to list the individual arguments.  The func-
  1168.                   tion, AllocRingBuffer, is provided in C source form on
  1169.                   the disk and included in the COMM_x libraries.  This
  1170.                   function allocates the ring buffer memory and initial-
  1171.                   izes the required port structure members.
  1172.  
  1173.                   The return values for async_open are different and may
  1174.                   have a different meaning than in earlier versions.
  1175.  
  1176.                   If a port is opened with an empty parameter string
  1177.                   (using "" for the parameters), then the port is opened
  1178.                   at its current settings and the port member BPDSstr is
  1179.                   set to the string representation of those values.
  1180.  
  1181.                   Async_open no longer checks the BIOS ram area at 40:0
  1182.                   to verify that a port actually exists.  There were too
  1183.                   many compatibles that did not store the proper values
  1184.                   there.
  1185.  
  1186.                   The maximum combined size of the receive and transmit
  1187.                   buffers for each port is 32K - 1.
  1188.  
  1189.                   FAR ring buffers in small and medium memory model
  1190.                   programs is now supported.  Use of FAR buffers does
  1191.                   not in any way affect the speed of the routines.
  1192.  
  1193.  
  1194.  
  1195.  
  1196.  
  1197.  
  1198.          async_peek
  1199.          ---------------------------------------------------------------
  1200.  
  1201.          Purpose: Indexed receive ring buffer look ahead function.
  1202.  
  1203.          Format:  int async_peek(port, index);
  1204.                    ASYNC *port;       Pointer to ASYNC structure
  1205.                    int index;         Index value
  1206.  
  1207.          Examples:
  1208.  
  1209.                   ASYNC *port;
  1210.                   char ch, buf[10];
  1211.                   int i;
  1212.  
  1213.                    /* peek next char in receive ring buffer */
  1214.                   ch = async_peek(port, 0);
  1215.  
  1216.                    /* peek next 10 chars in receive ring buffer */
  1217.                   for (i = 0; i < 10; i++)
  1218.                       buf[i] = async_peek(port, i);
  1219.  
  1220.          Returns: This function returns the character in the receive
  1221.                   ring buffer at the indexed position.  If an attempt is
  1222.                   made to peek deeper in the ring buffer than there are
  1223.                   characters in the ring buffer, -1 (0xffff) is
  1224.                   returned.
  1225.  
  1226.          Remarks: No characters are removed from the ring buffer by this
  1227.                   function.
  1228.  
  1229.                   The index value is 0 based.
  1230.  
  1231.                   To avoid confusing the character, '\0xff', from the
  1232.                   error return value, 0xffff, use an integer size
  1233.                   variable for the return value.  The character '\0xff'
  1234.                   is returned as 0x00ff and the error condition is
  1235.                   returned as 0xffff.
  1236.  
  1237.  
  1238.  
  1239.  
  1240.  
  1241.  
  1242.          async_regs
  1243.          ---------------------------------------------------------------
  1244.  
  1245.          Purpose: Provides direct access to the UART registers.
  1246.  
  1247.          Format:  int async_regs(port, reg_ofst, value);
  1248.                    ASYNC *port;       Pointer to ASYNC structure
  1249.                    int reg_ofst;      Offset of register from base adrs
  1250.                    int value;         Value to write or -1 if reading
  1251.  
  1252.          Examples:
  1253.  
  1254.                   ASYNC *port;
  1255.                   int LCRvalue;
  1256.  
  1257.                    /* read the line control register */
  1258.                   LCRvalue = async_regs(port, LCRreg, RDreg);
  1259.  
  1260.                    /* write a 0 to the modem control register */
  1261.                   async_regs(port, MCRreg, 0);
  1262.  
  1263.          Returns: When reading a register, the return value is the value
  1264.                   of the UART register that was read.  When writing a
  1265.                   register, the return value is undefined.
  1266.  
  1267.          Remarks: The following values for register offsets are defined
  1268.                   in COMM.H for use with async_regs:
  1269.                     RXreg, TXreg - receive & transmit regs, value = 0
  1270.                     IERreg - interrupt enable register,     value = 1
  1271.                     IIDreg - interrupt identification reg,  value = 2
  1272.                     FCRreg - FIFO control register          value = 2
  1273.                     LCRreg - line control register,         value = 3
  1274.                     MCRreg - modem control register,        value = 4
  1275.                     LSRreg - line status register,          value = 5
  1276.                     MSRreg - modem status register,         value = 6
  1277.                     LObaud - offset of low baud divisor,    value = 0
  1278.                     HIbaud - offset of high baud divisor,   value = 1
  1279.                   Also RDreg is defined as -1 for use when reading one
  1280.                   of the UART registers.  See the examples.  See
  1281.                   cautions on the following page before using this
  1282.                   function.
  1283.  
  1284.  
  1285.  
  1286.  
  1287.  
  1288.  
  1289.          async_regs
  1290.          ---------------------------------------------------------------
  1291.  
  1292.          Remarks (continued):
  1293.  
  1294.                   This function is provided primarily as a debugging
  1295.                   tool.  Reading or writing to the UART registers while
  1296.                   operating in an interrupt driven mode can cause
  1297.                   several types of problems.  Do not use this function
  1298.                   unless you know what you are doing.  Do not read the
  1299.                   RXreg, IIDreg, LSRreg, or MSRreg on an open port
  1300.                   except for debugging purposes.  Do not write any of
  1301.                   the registers.
  1302.  
  1303.                   The function may be used on a port that has not yet
  1304.                   been opened if the ComBase member of the port struc-
  1305.                   ture has been set.  When async_regs is used with an
  1306.                   unopened port the UART registers may be read or writ-
  1307.                   ten without restriction.
  1308.  
  1309.  
  1310.  
  1311.  
  1312.  
  1313.  
  1314.          async_reset
  1315.          ---------------------------------------------------------------
  1316.  
  1317.          Purpose: Clear parity error bit, framing error bit, character
  1318.                   overrun bit, receive buffer overflow bit, and break
  1319.                   signal received bit in the the Stat1 byte.
  1320.  
  1321.          Format:  void async_reset(port);
  1322.                    ASYNC *port;       Pointer to ASYNC structure
  1323.  
  1324.          Example:
  1325.  
  1326.                   ASYNC *port;
  1327.  
  1328.                   if (error)
  1329.                       async_reset(port);
  1330.  
  1331.  
  1332.          Returns: No return value
  1333.  
  1334.          Remarks: This function is implemented as a macro.  See also
  1335.                   async_rx and async_stat.
  1336.  
  1337.  
  1338.  
  1339.  
  1340.  
  1341.  
  1342.          async_restart
  1343.          ---------------------------------------------------------------
  1344.  
  1345.          Purpose: Re-initialize an already opened serial port
  1346.  
  1347.          Format:  void async_restart(port);
  1348.                    ASYNC *port;       Pointer to ASYNC structure
  1349.  
  1350.          Example:
  1351.  
  1352.                   ASYNC *port;
  1353.  
  1354.                   async_restart(port);
  1355.  
  1356.  
  1357.          Returns: No return value
  1358.  
  1359.          Remarks: Async_restart resets the interrupt vector, UART regis-
  1360.                   ters, and 8259 interrupt controller mask to the values
  1361.                   necessary for interrupt driven operation.  It also
  1362.                   flushes the receive and transmit buffers and resets
  1363.                   the Stat1 byte.  Use this function to restart a comm
  1364.                   port after spawning a program that may have altered
  1365.                   the interrupt vector, UART regs, or interrupt mask.
  1366.  
  1367.                   See also async_stop.
  1368.  
  1369.  
  1370.  
  1371.  
  1372.  
  1373.  
  1374.          async_rts
  1375.          ---------------------------------------------------------------
  1376.  
  1377.          Purpose: Sets or resets the Request to Send signal.
  1378.  
  1379.          Format:  void async_rts(port, flag);
  1380.                    ASYNC *port;       Pointer to ASYNC structure
  1381.                    int flag;          Set/Reset RTS flag
  1382.  
  1383.          Example:
  1384.  
  1385.                   ASYNC *port;
  1386.  
  1387.                   if (WantToDropRTS)
  1388.                       async_rts(port, 0);
  1389.                   else if (WantRTShigh)
  1390.                       async_rts(port, 1);
  1391.  
  1392.  
  1393.          Returns: No return value
  1394.  
  1395.          Remarks: The RTS signal is primarily used for hardware hand-
  1396.                   shaking.  When a port is first opened RTS is set HIGH
  1397.                   (enabled).  When the port is closed, it is restored to
  1398.                   the condition it was in when the port was opened.  To
  1399.                   force RTS low when closing a port, regardless of its
  1400.                   state when the port was opened, AND the port member,
  1401.                   OldMCR with NOT B_RTS.  To force RTS to remain high
  1402.                   when the port is closed, OR OldMCR with B_RTS.
  1403.  
  1404.                     Force low:    port->OldMCR &= ~B_RTS;
  1405.                                   async_close(port);
  1406.  
  1407.                     Force high:   port->OldMCR |= B_RTS;
  1408.                                   async_close(port);
  1409.  
  1410.  
  1411.  
  1412.  
  1413.  
  1414.  
  1415.          async_rx
  1416.          ---------------------------------------------------------------
  1417.  
  1418.          Purpose: Gets one character from the receive ring buffer.
  1419.  
  1420.          Format:  int async_rx(port);
  1421.                    ASYNC *port;       Pointer to ASYNC structure
  1422.  
  1423.          Examples:
  1424.  
  1425.                   ASYNC *port;
  1426.                   int rxch;
  1427.  
  1428.                   rxch = async_rx(port);       /* rxch == Stat1/char */
  1429.  
  1430.                   rxch = async_rx(port) & 0xff;      /* rxch == char */
  1431.  
  1432.                    /* chk if char available & process only if it was */
  1433.                   if (!((rxch = async_rx(port)) & B_RXEMPTY)
  1434.                       procRxdChar(rxch & 0xff);
  1435.  
  1436.          Returns: Async_rx returns the character received as the low
  1437.                   byte and the Stat1 status byte as the high byte.  If
  1438.                   the receive ring buffer was empty when async_rx was
  1439.                   called the low byte will be 0 and the high byte will
  1440.                   have the B_RXEMPTY bit set.  The Stat1 byte is a bit
  1441.                   mapped value that reflects parity errors, framing
  1442.                   errors, character overrun errors, receive buffer
  1443.                   overflow errors, receive buffer empty, break signal
  1444.                   received, and carrier lost.  If no receive errors
  1445.                   have occurred, a break signal has not been received,
  1446.                   and a carrier is present, Stat1 will be 0.
  1447.  
  1448.  
  1449.  
  1450.  
  1451.  
  1452.  
  1453.          async_rx
  1454.          ---------------------------------------------------------------
  1455.  
  1456.          Remarks: Error bits set in the Stat1 byte are not necessarily
  1457.                   associated with the character just taken out of the
  1458.                   receive ring buffer.  In fact, they probably are not.
  1459.                   The error bits are set when the error is detected and
  1460.                   reset when async_reset is called.  For example:
  1461.  
  1462.                    1) 20 bytes of data are received with no errors.
  1463.                    2) Async_rx has been called 10 times so 10 characters
  1464.                       have been taken out of the ring buffer and 10 of
  1465.                       the bytes with no errors are still in the buffer.
  1466.                    3) A parity error occurs on the next byte received
  1467.                       from the UART -- the 11th byte in the receive ring
  1468.                       buffer.
  1469.                    4) The next byte taken out of the buffer, which is
  1470.                       the first of the 10 remaining good bytes will have
  1471.                       the parity error bit in the Stat1 byte.  It will
  1472.                       remain set until async_reset is called.
  1473.  
  1474.                   If the 'ignore characters with errors' bit is set (see
  1475.                   async_ignerr), then characters that have either parity
  1476.                   or framing errors are never placed in the receive ring
  1477.                   buffer.  They are read from the UART and discarded.
  1478.                   The error bits in Stat1 are set regardless of the
  1479.                   setting of the 'ignore characters with errors' bit.
  1480.  
  1481.  
  1482.  
  1483.  
  1484.  
  1485.  
  1486.          async_rxblk
  1487.          ---------------------------------------------------------------
  1488.  
  1489.          Purpose: Retrieves a block of characters from the receive ring
  1490.                   buffer.
  1491.  
  1492.          Format:  int async_rxblk(port, buf, maxchars);
  1493.                    ASYNC *port;       Pointer to ASYNC structure
  1494.                    char *buf;         Buffer for received data
  1495.                    int maxchars;      Maximum number of chars to read
  1496.  
  1497.          Example:
  1498.  
  1499.                   ASYNC *port;
  1500.                   char buf[256];
  1501.                   int bytesRead;
  1502.  
  1503.                   bytesRead = async_rxblk(port, buf, sizeof(buf));
  1504.  
  1505.          Returns: Async_rxblk returns the number of bytes read.  This
  1506.                   value will be 'maxchars' if there are that many bytes
  1507.                   available in the receive buffer.  If there are not
  1508.                   'maxchars' in the receive buffer, the entire contents
  1509.                   of the receive buffer will be moved to 'buf' and the
  1510.                   return value will be the number of bytes that were in
  1511.                   the buffer.
  1512.  
  1513.          Remarks: Very fast way to read data.  See also async_rx and
  1514.                   async_rxblkch.
  1515.  
  1516.  
  1517.  
  1518.  
  1519.  
  1520.  
  1521.          async_rxblkch
  1522.          ---------------------------------------------------------------
  1523.  
  1524.          Purpose: Retrieve bytes from the receive ring buffer until the
  1525.                   specified character is found, 'maxchars' are read, or
  1526.                   the receive ring buffer is emptied.
  1527.  
  1528.          Format:
  1529.            int async_rxblkch(port, buf, maxchars, keychar, includekey);
  1530.             ASYNC *port;      Pointer to ASYNC structure
  1531.             char *buf;        Destination for bytes read
  1532.             int maxchars;     Maximum number of chars to read
  1533.             char keychar;     Character to scan for
  1534.             int includekey;   Flag set if 'keychar' is to be read also
  1535.  
  1536.          Example:
  1537.  
  1538.            ASYNC *port;
  1539.            char buf[256];
  1540.            int bytesRead;
  1541.            int foundkey;
  1542.  
  1543.            bytesRead = async_rxblkch(port, buf, sizeof(buf), '\n', 1);
  1544.            if (bytesRead < 0)
  1545.                bytesRead = -bytesRead, foundkey = TRUE;
  1546.             else
  1547.                foundkey = FALSE;
  1548.  
  1549.          Returns: This function returns the number of bytes read if the
  1550.                   'keychar' is not found.  If the 'keychar' is found the
  1551.                   2's complement of the number of bytes read is
  1552.                   returned.
  1553.  
  1554.  
  1555.  
  1556.  
  1557.  
  1558.  
  1559.          async_rxblkch
  1560.          ---------------------------------------------------------------
  1561.  
  1562.          Remarks: The 'includekey' flag, which is the last argument of
  1563.                   the function, determines whether or not the 'keychar'
  1564.                   is to be included if it is found.  If the flag is 1
  1565.                   and the 'keychar' is found it will be the last char-
  1566.                   acter in the user buffer.  If this flag is 0 and the
  1567.                   'keychar' is found, the 'keychar' is left in the re-
  1568.                   ceive ring buffer and will be the first character read
  1569.                   when you next call one of the async_rx type functions.
  1570.                   This can cause a problem if you set this flag to 0 and
  1571.                   the 'keychar' is the first character in the receive
  1572.                   buffer.  The function will return 0, which would seem
  1573.                   to indicate that there were no bytes in the buffer.
  1574.                   Actually the character was found but since you are not
  1575.                   taking it out of the ring buffer zero bytes are read.
  1576.                   There are two ways to check for this condition.  You
  1577.                   can first call async_rxcnt to verify there are bytes
  1578.                   in the receive buffer and then call async_rxblkch.  If
  1579.                   async_rxblkch returns 0, the 'keychar' is there and is
  1580.                   the first byte in the buffer.  The other method is to
  1581.                   use async_peek to see what the next character in the
  1582.                   receive buffer is before calling async_rxblkch.
  1583.  
  1584.                   A 2's complement value of the bytes read is returned
  1585.                   by async_rxblkch when the 'keychar' is found.  For
  1586.                   actual bytes use:
  1587.                       bytes = async_rxblkch( ....);
  1588.                       if (bytes < 0)
  1589.                           bytes = -bytes;
  1590.                   A byte count less than zero is the signal the
  1591.                   'keychar' was found.  (Except for the circumstance
  1592.                   noted in the previous paragraph).
  1593.  
  1594.                   See async_rx, async_rxblk, async_rxcnt, async_peek.
  1595.  
  1596.  
  1597.  
  1598.  
  1599.  
  1600.  
  1601.          async_rxcnt
  1602.          ---------------------------------------------------------------
  1603.  
  1604.          Purpose: Returns the number of bytes in the receive ring
  1605.                   buffer.
  1606.  
  1607.          Format:  int async_rxcnt(port);
  1608.                    ASYNC *port;       Pointer to ASYNC structure
  1609.  
  1610.          Example:
  1611.  
  1612.                   ASYNC *port;
  1613.  
  1614.                   BytesInRxBuf = async_rxcnt(port);
  1615.  
  1616.          Returns: Number of bytes in the receive ring buffer
  1617.  
  1618.          Remarks: This function is implemented as a macro.
  1619.  
  1620.  
  1621.  
  1622.  
  1623.  
  1624.  
  1625.          async_rxerr
  1626.          ---------------------------------------------------------------
  1627.  
  1628.          Purpose: Checks if a receive error has been detected.
  1629.  
  1630.          Format:  int async_rxerr(port);
  1631.                    ASYNC *port;       Pointer to ASYNC structure
  1632.  
  1633.          Example:
  1634.  
  1635.                   ASYNC *port;
  1636.                   int rxerr_status;
  1637.  
  1638.                   rxerr_status = async_rxerr(port);
  1639.  
  1640.          Returns: ZR if no receive errors have been detected, NZ if
  1641.                   receive error has been detected.
  1642.  
  1643.          Remarks: Types of receive errors that are detected by this
  1644.                   function are parity errors, framing errors, UART
  1645.                   receive register overflow, and receive ring buffer
  1646.                   overflow.  This information is also returned as the
  1647.                   high byte of the async_rx and async_stat functions.
  1648.                   This function is implemented as a macro.
  1649.  
  1650.                   See also async_rx, async_stat.
  1651.  
  1652.  
  1653.  
  1654.  
  1655.  
  1656.  
  1657.          async_rxflush
  1658.          ---------------------------------------------------------------
  1659.  
  1660.          Purpose: Empties out the receive ring buffer.
  1661.  
  1662.          Format:  void async_rxflush(port);
  1663.                    ASYNC *port;       Pointer to ASYNC structure
  1664.  
  1665.          Example:
  1666.  
  1667.                   ASYNC *port;
  1668.  
  1669.                   async_rxflush(port);
  1670.  
  1671.          Returns: This function does not have a return value
  1672.  
  1673.          Remarks: Clears the receive ring buffer and -- if a 16550 is
  1674.                   present in the system with its FIFOs activated --
  1675.                   resets the receiver FIFOs.  All data that was in the
  1676.                   buffer is lost.  If XON/XOFF flow control is being
  1677.                   used and an XOFF has been sent to the remote, this
  1678.                   function automatically sends an XON.  An XON is not
  1679.                   ALWAYS sent -- only if XFLOW control is in use and the
  1680.                   async interrupt routine has sent an XOFF.  It will not
  1681.                   clear false XOFFs the remote may have received.
  1682.  
  1683.  
  1684.  
  1685.  
  1686.  
  1687.  
  1688.          async_rxfree (5.40)
  1689.          ---------------------------------------------------------------
  1690.  
  1691.          Purpose: Returns the number of bytes left available in the
  1692.                   receive ring buffer for incoming characters.
  1693.  
  1694.          Format:  int async_rxfree(port);
  1695.                    ASYNC *port;       Pointer to ASYNC structure
  1696.  
  1697.          Example:
  1698.  
  1699.                   ASYNC *port;
  1700.  
  1701.                    RxBufFreeSpace = async_rxfree(port);
  1702.  
  1703.          Returns: Number of bytes that can be received without taking
  1704.                   any out before a receive buffer overflow will occur.
  1705.  
  1706.          Remarks: This function is implemented as a macro.
  1707.  
  1708.  
  1709.  
  1710.  
  1711.  
  1712.  
  1713.          async_setbpds
  1714.          ---------------------------------------------------------------
  1715.  
  1716.          Purpose: Change the baud rate, parity, number of data bits or
  1717.                   number of stop bits on an already opened port.
  1718.  
  1719.          Format:  int async_setbpds(port, params);
  1720.                    ASYNC *port;       Pointer to ASYNC structure
  1721.                    char *params;      Pointer to parameter string
  1722.  
  1723.          Example:
  1724.  
  1725.                   ASYNC *port;
  1726.                   int rcode;
  1727.  
  1728.                   rcode = async_setbpds(port, "2400E71");
  1729.  
  1730.          Returns: This function returns 0 if successful and the new
  1731.                   parameter string is copied to the port structure
  1732.                   member, BPDSstr.  Errors that can be returned are
  1733.                   R_BAUDERR, R_PARITYERR, R_DTABITERR, or R_STPBITERR.
  1734.                   If one of these error codes are returned, the port
  1735.                   settings are unchanged and the port member BPDSstr is
  1736.                   left unchanged.
  1737.  
  1738.                   See async_open for a more complete description of
  1739.                   these errors.
  1740.  
  1741.          Remarks: If 7 data bits is selected the StripMask is set to
  1742.                   strip the high bit off incoming data.  If 8 data bits
  1743.                   are selected the StripMask is disabled.
  1744.  
  1745.                   Valid baud rates are from 50 to 115200 baud.  Parity
  1746.                   may be 'E'ven, 'N'one, or 'O'dd.  The number of data
  1747.                   bits must be 7 or 8 and the number of stop bits must
  1748.                   be 1 or 2.  Do not use spaces, commas, or any other
  1749.                   type of punctuation in the parameter string.
  1750.  
  1751.                   See also async_open, async_strip.
  1752.  
  1753.  
  1754.  
  1755.  
  1756.  
  1757.  
  1758.          async_sndbrk
  1759.          ---------------------------------------------------------------
  1760.  
  1761.          Purpose: Enable or disable a break signal
  1762.  
  1763.          Format:  void async_sndbrk(port, Brkflag);
  1764.                    ASYNC *port;       Pointer to ASYNC structure
  1765.                    int Brkflag;       Set/Reset break signal flag
  1766.  
  1767.          Example:
  1768.  
  1769.                   ASYNC *port;
  1770.  
  1771.                    /* send break for 50 msec */
  1772.                   async_sndbrk(port, 1); /* enable break signal */
  1773.                   delay(50MSEC);         /* your delay function */
  1774.                   async_sndbrk(port, 0); /* disable break signal */
  1775.  
  1776.  
  1777.          Returns: No return value
  1778.  
  1779.          Remarks: This function causes the UART to send a continuous
  1780.                   break signal if it is called with the flag set to 1.
  1781.                   It must be called again with the flag set to 0 to
  1782.                   disable the break signal.
  1783.  
  1784.  
  1785.  
  1786.  
  1787.  
  1788.  
  1789.          async_stat
  1790.          ---------------------------------------------------------------
  1791.  
  1792.          Purpose: Get the current status of a port
  1793.  
  1794.          Format:  int async_stat(port, mask);
  1795.                    ASYNC *port;       Pointer to ASYNC structure
  1796.                    int mask;          Mask applied to return value
  1797.  
  1798.          Examples:
  1799.  
  1800.                   ASYNC *port;
  1801.                   int status;
  1802.  
  1803.                    /* status = all status bits */
  1804.                   status = async_stat(port, 0xffff);
  1805.  
  1806.                    /* check for XOFF received condition */
  1807.                   if (async_stat(port, B_XRXD))
  1808.                       do_something();
  1809.  
  1810.  
  1811.          Returns: Returns Stat1/Stat2 status bits after masking them
  1812.                   with the passed mask value.  Stat1 is the high byte
  1813.                   and Stat2 is the low byte of the return value.
  1814.  
  1815.                   Stat1 bit map:
  1816.                       Bit 7 = set if no carrier present
  1817.                       Bit 6 = receive ring buffer empty
  1818.                       Bit 5 = used by interrupt routines (always 0)
  1819.                       Bit 4 = break signal was detected
  1820.                       Bit 3 = framing error was detected
  1821.                       Bit 2 = parity error was detected
  1822.                       Bit 1 = character overrun error was detected
  1823.                       Bit 0 = receive ring buffer has overflowed
  1824.  
  1825.                   Stat2 bit map:
  1826.                       Bit 7 = carrier detect monitored for flow control
  1827.                       Bit 6 = XOFF rx'd or hardware flow control active
  1828.                       Bit 5 = data set ready monitored for flow control
  1829.                       Bit 4 = clear to send monitored for flow control
  1830.                       Bit 3 = transmit ring buffer is empty
  1831.                       Bit 2 = an XOFF has been sent by interrupt handler
  1832.                       Bit 1 = an XOFF has been received
  1833.                       Bit 0 = using XON/XOFF flow control
  1834.  
  1835.  
  1836.  
  1837.  
  1838.  
  1839.  
  1840.          async_stat
  1841.          ---------------------------------------------------------------
  1842.  
  1843.          Remarks: For some situations, it is more efficient to use one
  1844.                   of the other library functions targeted specifically
  1845.                   for the information you want.  For instance, instead
  1846.                   of calling:
  1847.                        async_stat(port, B_XRXD);
  1848.                   use:
  1849.                        async_xrxd(port);
  1850.  
  1851.                   The information in the Stat1 byte is also returned as
  1852.                   the high byte of the async_rx function.  Bits 0-4 of
  1853.                   Stat1 remain set until cleared by the async_reset
  1854.                   function.
  1855.  
  1856.                   Not all bits in the Stat2 and Stat1 port structure
  1857.                   members are kept updated on a constant basis so do not
  1858.                   try to check a condition by testing the Stat1 or Stat2
  1859.                   values in the ASYNC structure.  Use one of the docu-
  1860.                   mented functions or macros to be sure of getting the
  1861.                   correct result.
  1862.  
  1863.  
  1864.  
  1865.  
  1866.  
  1867.  
  1868.          async_stop
  1869.          ---------------------------------------------------------------
  1870.  
  1871.          Purpose: Temporarily disables interrupt driven operation of an
  1872.                   already opened port.
  1873.  
  1874.          Format:  void async_stop(port);
  1875.                    ASYNC *port;       Pointer to ASYNC structure
  1876.  
  1877.          Example:
  1878.  
  1879.                   ASYNC *port;
  1880.                   int x, inhdl, outhdl, errhdl;
  1881.  
  1882.                   async_stop(port);               /* release port */
  1883.                    /* redirect console to async port */
  1884.                   x = open("COM1", O_RDWR|O_BINARY);
  1885.                   inhdl = dup(0);  outhdl = dup(1);  errhdl = dup(2);
  1886.                   dup2(x, 0);  dup2(x, 1);  dup2(x, 2);
  1887.                    /* run a redirected DOS shell */
  1888.                   spawnlp(P_WAIT, "COMMAND.COM", "COMMAND.COM", NULL);
  1889.                    /* restore stdin, stdout, stderr */
  1890.                   close(x);
  1891.                   dup2(inhdl, 0);   close(inhdl);
  1892.                   dup2(outhdl, 1);  close(outhdl);
  1893.                   dup2(errhdl, 2);  close(errhdl);
  1894.                   async_restart(port);   /* regain control of port */
  1895.  
  1896.          Returns: No return value
  1897.  
  1898.          Remarks: Call this function before spawning a program that will
  1899.                   be doing its own port I/O, such as an external commun-
  1900.                   ications program or a redirected DOS shell.  After the
  1901.                   other application has completed, call async_restart to
  1902.                   re-enable interrupt operation.
  1903.  
  1904.                   This function disables interrupts for the named port
  1905.                   by clearing UART's interrupt enable register and the
  1906.                   OUT2 bit of its modem control register.
  1907.  
  1908.                   See also async_restart.
  1909.  
  1910.  
  1911.  
  1912.  
  1913.  
  1914.  
  1915.          async_strip
  1916.          ---------------------------------------------------------------
  1917.  
  1918.          Purpose: Set the strip mask for received characters.
  1919.  
  1920.          Format:  void async_strip(port, mask);
  1921.                    ASYNC *port;       Pointer to ASYNC structure
  1922.                    char mask;         Strip mask
  1923.  
  1924.          Example:
  1925.  
  1926.                   ASYNC *port;
  1927.  
  1928.                   async_strip(port, '\x7f');
  1929.  
  1930.          Returns: No return value
  1931.  
  1932.          Remarks: The strip mask is automatically set to 0x7f when the
  1933.                   parameters are set for 7 data bits and to 0xff when 8
  1934.                   data bits are used.  All incoming data is ANDed with
  1935.                   the strip mask before it is placed in the receive ring
  1936.                   buffer.  This function is implemented as a macro.
  1937.  
  1938.  
  1939.  
  1940.  
  1941.  
  1942.  
  1943.          async_tx
  1944.          ---------------------------------------------------------------
  1945.  
  1946.          Purpose: Send 1 character to a port.
  1947.  
  1948.          Format:  int async_tx(port, ch);
  1949.                    ASYNC *port;       Pointer to ASYNC structure
  1950.                    char ch;           Character to transmit
  1951.  
  1952.          Example:
  1953.  
  1954.                   ASYNC *port;
  1955.  
  1956.                    /* send a CR/LF to a port */
  1957.                   async_tx(port, '\r');
  1958.                   async_tx(port, '\n');
  1959.  
  1960.  
  1961.          Returns: Returns the number of bytes left available in the
  1962.                   transmit ring buffer unless the ring buffer was full
  1963.                   when the function was called.  R_TXERR is returned if
  1964.                   the transmit ring buffer was full and the character
  1965.                   that was to be transmitted is not placed in the ring
  1966.                   buffer.
  1967.  
  1968.          Remarks: The error return value, R_TXERR, is a negative number.
  1969.                   The bytes free return value can never be negative.
  1970.  
  1971.                   See also async_txblk, async_txfree.
  1972.  
  1973.  
  1974.  
  1975.  
  1976.  
  1977.  
  1978.          async_txblk
  1979.          ---------------------------------------------------------------
  1980.  
  1981.          Purpose: Send a block of characters to a port.
  1982.  
  1983.          Format:  int async_txblk(port, buf, count);
  1984.                    ASYNC *port;       Pointer to ASYNC structure
  1985.                    char *buf;         Pointer to block to transmit
  1986.                    int count;         Size of block in bytes
  1987.  
  1988.          Examples:
  1989.  
  1990.                   ASYNC *port;
  1991.                   char buf[128];
  1992.                   static char *msg = "Send this message\r\n");
  1993.  
  1994.                   put_data_in_buf();
  1995.                   async_txblk(port, buf, sizeof(buf));
  1996.                   async_txblk(port, msg, strlen(msg));
  1997.  
  1998.          Returns: Returns the number of bytes left available in the
  1999.                   transmit ring buffer unless the ring buffer would not
  2000.                   hold the entire block when the function was called.
  2001.                   R_TXERR is returned if there was no room for the
  2002.                   block and none of the bytes in the block are sent.
  2003.  
  2004.          Remarks: This function is much faster than using repeated calls
  2005.                   to async_tx when multiple bytes are being transmitted.
  2006.                   The error return value, R_TXERR, is a negative number.
  2007.                   The bytes free return value can never be negative.
  2008.  
  2009.                   See also async_tx, async_txfree.
  2010.  
  2011.  
  2012.  
  2013.  
  2014.  
  2015.  
  2016.          async_txcnt (5.40)
  2017.          ---------------------------------------------------------------
  2018.  
  2019.          Purpose: Returns the number of bytes in the transmit ring
  2020.                   buffer.
  2021.  
  2022.          Format:  int async_txcnt(port);
  2023.                    ASYNC *port;       Pointer to ASYNC structure
  2024.  
  2025.          Example:
  2026.  
  2027.                   ASYNC *port;
  2028.  
  2029.                   BytesInTxBuf = async_txcnt(port);
  2030.  
  2031.          Returns: Number of untransmitted bytes in the transmit ring
  2032.                   buffer.
  2033.  
  2034.          Remarks: This function is implemented as a macro.  If a 16550
  2035.                   is in the system with its FIFOs active, there may be
  2036.                   up to 16 (depends on what async_FIFOtxlvl is set at --
  2037.                   the default is 3 bytes) more bytes of untransmitted
  2038.                   data in the 16550 FIFOs plus 1 byte in the UART
  2039.                   transmit hold register.  With no 16550 there may still
  2040.                   be up to 2 untransmitted bytes -- one in the UART's
  2041.                   transmit hold register and one in the UART's transmit
  2042.                   shift register.  To monitor for a transmit buffer
  2043.                   empty condition use async_txempty.
  2044.  
  2045.  
  2046.  
  2047.  
  2048.  
  2049.  
  2050.          async_txempty
  2051.          ---------------------------------------------------------------
  2052.  
  2053.          Purpose: Checks if transmit ring buffer is empty.
  2054.  
  2055.          Format:  int async_txempty(port);
  2056.                    ASYNC *port;       Pointer to ASYNC structure
  2057.  
  2058.          Example:
  2059.  
  2060.                   ASYNC *port;
  2061.  
  2062.                    /* wait for transmit ring buffer to empty out */
  2063.                   while (!async_txempty(port))
  2064.                       ;
  2065.  
  2066.          Returns: NZ if the transmit ring buffer is empty, ZR if the
  2067.                   buffer still has characters to be transmitted.
  2068.  
  2069.          Remarks: This function is implemented as a macro.  If a 16550
  2070.                   is in the system with its FIFOs active, there may be
  2071.                   up to 16 (depends on what async_FIFOtxlvl is set at --
  2072.                   the default is 3 bytes) more bytes of untransmitted
  2073.                   data in the 16550 FIFOs plus 1 byte in the UART
  2074.                   transmit hold register.  With no 16550 there may still
  2075.                   be up to 2 untransmitted bytes -- one in the UART's
  2076.                   transmit hold register and one in the UART's transmit
  2077.                   shift register.
  2078.  
  2079.  
  2080.  
  2081.  
  2082.  
  2083.  
  2084.          async_txflush
  2085.          ---------------------------------------------------------------
  2086.  
  2087.          Purpose: Flushes the transmit ring buffer.
  2088.  
  2089.          Format:  void async_txflush(port);
  2090.                    ASYNC *port;       Pointer to ASYNC structure
  2091.  
  2092.          Example:
  2093.  
  2094.                   ASYNC *port;
  2095.  
  2096.                   async_txflush(port);
  2097.  
  2098.  
  2099.          Returns: No return value
  2100.  
  2101.          Remarks: Clears the transmit ring buffer and -- if a 16550
  2102.                   operating in FIFO mode is in the system -- resets the
  2103.                   transmit FIFOs.  All characters in the buffer that
  2104.                   have not been transmitted are lost.
  2105.  
  2106.  
  2107.  
  2108.  
  2109.  
  2110.  
  2111.          async_txfree
  2112.          ---------------------------------------------------------------
  2113.  
  2114.          Purpose: Returns the number of bytes left available in the
  2115.                   transmit ring buffer.
  2116.  
  2117.          Format:  int async_txfree(port);
  2118.                    ASYNC *port;       Pointer to ASYNC structure
  2119.  
  2120.          Example:
  2121.  
  2122.                   ASYNC *port;
  2123.                   int tx_bytes_available;
  2124.  
  2125.                   tx_bytes_available = async_txfree(port);
  2126.  
  2127.  
  2128.          Returns: Number of bytes of free space left in the transmit
  2129.                   buffer.
  2130.  
  2131.          Remarks: The number of free bytes left in the transmit ring
  2132.                   buffer is also the return value of async_tx and
  2133.                   async_txblk.  This function is implemented as a macro.
  2134.  
  2135.  
  2136.  
  2137.  
  2138.  
  2139.  
  2140.          async_xany
  2141.          ---------------------------------------------------------------
  2142.  
  2143.          Purpose: Checks if accepting the first character after an XOFF
  2144.                   is received as the XON character.  DOES NOT enable any
  2145.                   character XON (use async_xflow).
  2146.  
  2147.          Format:  int async_xany(port);
  2148.                    ASYNC *port;       Pointer to ASYNC structure
  2149.  
  2150.          Example:
  2151.  
  2152.                   ASYNC *port;
  2153.                   int rcode;
  2154.  
  2155.                   rcode = async_xany(port);
  2156.  
  2157.          Returns: Not zero if first character after an XOFF is to be
  2158.                   treated as an XON.  Zero if a real XON is required to
  2159.                   clear an XOFF.
  2160.  
  2161.          Remarks: This function is implemented as a macro.  See also
  2162.                   async_xflow.
  2163.  
  2164.  
  2165.  
  2166.  
  2167.  
  2168.  
  2169.          async_xflow
  2170.          ---------------------------------------------------------------
  2171.  
  2172.          Purpose: Enables/disables use of XON/XOFF flow control.
  2173.  
  2174.          Format:  void async_xflow(port, flag);
  2175.                    ASYNC *port;       Pointer to ASYNC structure
  2176.                    int flag;          Enable/Disable & any char XON flag
  2177.  
  2178.          Examples:
  2179.  
  2180.                   ASYNC *port;
  2181.  
  2182.                   async_xflow(port, B_XUSE); /* use flow control */
  2183.                   async_xflow(port, 0);      /* disable flow control */
  2184.  
  2185.                    /* use XON/XOFF flow control with any char being
  2186.                       accepted as an XON */
  2187.                   async_xflow(port, B_XUSE | B_XONANY);
  2188.  
  2189.                    /* enable XON/XOFF on transmit side only */
  2190.                   async_xflow(port, B_XUSET);
  2191.  
  2192.                    /* enable XON/XOFF on receive side only */
  2193.                   async_xflow(port, B_XUSER);
  2194.  
  2195.          Returns: No return value
  2196.  
  2197.          Remarks: Passing B_XUSET enables the transmission of XON/XOFF
  2198.                   characters when the receive buffer fills to the 'trip'
  2199.                   levels discussed in the following paragraph.  Incoming
  2200.                   XON/XOFFs are not regarded as flow control characters
  2201.                   and are stored in the ring buffer.  Passing B_XUSER,
  2202.                   enables recognition of received XON/XOFFs as flow
  2203.                   characters but does not enable transmission of
  2204.                   XON/XOFF at the trip levels.  If B_XUSE is passed,
  2205.                   both transmission and recognition of XON/XOFF as flow
  2206.                   characters is enabled (the same as B_XUSET | B_XUSER).
  2207.                   ORing B_XONANY with either B_XUSE or B_XUSER causes
  2208.                   the first character received after an XOFF to be
  2209.                   treated as the XON unless that character is another
  2210.                   XOFF.  Passing zero as the flag disables XON/XOFF flow
  2211.                   control.  The default is no flow control.
  2212.  
  2213.  
  2214.  
  2215.  
  2216.  
  2217.  
  2218.          async_xflow
  2219.          ---------------------------------------------------------------
  2220.  
  2221.          Remarks (continued):
  2222.  
  2223.                   The port structure member, XoffTrip, determines when
  2224.                   an XOFF will be sent.  Whenever the number of bytes
  2225.                   left available in receive buffer falls below XoffTrip,
  2226.                   an XOFF is sent.  The default value of XoffTrip is 25%
  2227.                   of the size of the receive buffer so an XOFF is sent
  2228.                   whenever the receive buffer is 75% full.
  2229.  
  2230.                   The port structure member, XonTrip, determines when an
  2231.                   XON will be sent.  Whenever the number of bytes left
  2232.                   available in the receive buffer rises above XonTrip,
  2233.                   an XON will be sent.  Its default value is 50% of the
  2234.                   size of the receive buffer.
  2235.  
  2236.                   The port structure member, XTxRptInit, determines how
  2237.                   many bytes may be received after an XOFF is sent
  2238.                   before another XOFF is sent.  Its default value is
  2239.                   6.25% of the size of the receive buffer or 160 bytes,
  2240.                   whichever is less.
  2241.  
  2242.                   XoffTrip, XonTrip, and XTxRptInit may all be changed
  2243.                   from their default values by directly accessing the
  2244.                   port structure.  To do this:
  2245.  
  2246.                       ASYNC *port;
  2247.                      /* send XOFF when 300 bytes left in rx ring buf */
  2248.                       port->XoffTrip = 300;
  2249.                      /* send XON when 350 bytes left in rx ring buf */
  2250.                       port->XonTrip = 350;
  2251.  
  2252.                   Be sure to keep the XonTrip level higher than the
  2253.                   XoffTrip level.  The values are for bytes left
  2254.                   available not bytes used.
  2255.  
  2256.                   The XTxRptInit value is used to automatically send
  2257.                   another XOFF in the event the first one was ignored.
  2258.                   Instead of sending an XOFF character everytime another
  2259.                   character is received, the interrupt routines wait for
  2260.                   'XTxRptInit' characters to be received and then repeat
  2261.                   the XOFF.  If this value is set to low some systems
  2262.                   that allow any character to be an XON will treat the
  2263.                   repeated XOFF character as an XON.
  2264.  
  2265.  
  2266.  
  2267.  
  2268.  
  2269.  
  2270.          async_xoffclr
  2271.          ---------------------------------------------------------------
  2272.  
  2273.          Purpose: Manually clears an XOFF received condition
  2274.  
  2275.          Format:  void async_xoffclr(port);
  2276.                    ASYNC *port;       Pointer to ASYNC structure
  2277.  
  2278.          Example:
  2279.  
  2280.                   ASYNC *port;
  2281.  
  2282.                   async_xoffclr(port);
  2283.  
  2284.          Returns: No return value
  2285.  
  2286.          Remarks: Async_xoffclr has the same effect as if the remote
  2287.                   system had sent an XON.  This will unstop the system
  2288.                   in the event a false XOFF is received or the remote's
  2289.                   XON was lost.  Use this function with caution.  Unless
  2290.                   something goes wrong, the remote will clear XOFF cond-
  2291.                   itions automatically by sending an XON.  If an XOFF is
  2292.                   manually cleared, the remote site may be overran and
  2293.                   lose data.  For use only when XON/XOFF flow control
  2294.                   has been activated.
  2295.  
  2296.                   See also async_xoffset.
  2297.  
  2298.  
  2299.  
  2300.  
  2301.  
  2302.  
  2303.          async_xoffset
  2304.          ---------------------------------------------------------------
  2305.  
  2306.          Purpose: Manually sets an XOFF received condition
  2307.  
  2308.          Format:  void async_xoffset(port);
  2309.                    ASYNC *port;       Pointer to ASYNC structure
  2310.  
  2311.          Example:
  2312.  
  2313.                   ASYNC *port;
  2314.  
  2315.                   async_xoffset(port);
  2316.  
  2317.          Returns: No return value
  2318.  
  2319.          Remarks: Forces the local site to act as though an XOFF had
  2320.                   been received.  Transmit interrupts are disabled until
  2321.                   the remote sends an XON or you call async_xoffclr.
  2322.                   For use only when XON/XOFF flow control has been
  2323.                   activated.
  2324.  
  2325.                   See also async_xoffclr.
  2326.  
  2327.  
  2328.  
  2329.  
  2330.  
  2331.  
  2332.          async_xrxd
  2333.          ---------------------------------------------------------------
  2334.  
  2335.          Purpose: Check if an XOFF has been received and has activated a
  2336.                   flow control halt.
  2337.  
  2338.          Format:  int async_xrxd(port);
  2339.                    ASYNC *port;       Pointer to ASYNC structure
  2340.  
  2341.          Example:
  2342.  
  2343.                   ASYNC *port;
  2344.                   int rcode;
  2345.  
  2346.                   rcode = async_xrxd(port);
  2347.  
  2348.          Returns: Not zero if an XOFF has been received and an XON has
  2349.                   not been received to clear it.  Returns zero if XOFF
  2350.                   flow halt is not currently active.
  2351.  
  2352.          Remarks: This function is implemented as a macro.  See also
  2353.                   async_xoffclr, async_xtxd.
  2354.  
  2355.  
  2356.  
  2357.  
  2358.  
  2359.  
  2360.          async_xtxd
  2361.          ---------------------------------------------------------------
  2362.  
  2363.          Purpose: Check if an XOFF has been sent
  2364.  
  2365.          Format:  int async_xtxd(port);
  2366.                    ASYNC *port;       Pointer to ASYNC structure
  2367.  
  2368.          Example:
  2369.  
  2370.                   ASYNC *port;
  2371.                   int rcode;
  2372.  
  2373.                   rcode = async_xtxd(port);
  2374.  
  2375.          Returns: Not zero if an XOFF has not been sent by the receive
  2376.                   interrupt routine and an XON has not been sent to
  2377.                   clear it.  Returns zero if an XOFF has not been sent.
  2378.  
  2379.          Remarks: This function is implemented as a macro.  See also
  2380.                   async_xoffclr, async_xrxd.
  2381.  
  2382.  
  2383.  
  2384.  
  2385.  
  2386.  
  2387.          async_xuse
  2388.          ---------------------------------------------------------------
  2389.  
  2390.          Purpose: Check if XON/XOFF protocol is currently being used
  2391.  
  2392.          Format:  int async_xuse(port);
  2393.                    ASYNC *port;       Pointer to ASYNC structure
  2394.  
  2395.          Example:
  2396.  
  2397.                   ASYNC *port;
  2398.  
  2399.                   rcode = async_xuse(port);
  2400.  
  2401.          Returns: Not zero if XON/XOFF protocol is being used on either
  2402.                   the transmit or receive sides, zero if XON/XOFF flow
  2403.                   is not being used at all.
  2404.  
  2405.          Remarks: This function is implemented as a macro.  See
  2406.                   async_xflow, async_xuset, async_xuser.
  2407.  
  2408.  
  2409.  
  2410.  
  2411.  
  2412.  
  2413.          async_xuser
  2414.          ---------------------------------------------------------------
  2415.  
  2416.          Purpose: Check if XON/XOFF protocol is enabled on the receive
  2417.                   side (receiver recognizes XON/XOFF as flow control).
  2418.  
  2419.          Format:  int async_xuser(port);
  2420.                    ASYNC *port;       Pointer to ASYNC structure
  2421.  
  2422.          Example:
  2423.  
  2424.                   ASYNC *port;
  2425.  
  2426.                   rcode = async_xuser(port);
  2427.  
  2428.          Returns: Not zero if XON/XOFF protocol is being used on the
  2429.                   receive side, zero if it is not.
  2430.  
  2431.          Remarks: This function is implemented as a macro.  See
  2432.                   async_xflow, async_xuset, async_xuse.
  2433.  
  2434.  
  2435.  
  2436.  
  2437.  
  2438.  
  2439.          async_xuset
  2440.          ---------------------------------------------------------------
  2441.  
  2442.          Purpose: Check if XON/XOFF protocol is enabled on the transmit
  2443.                   side (transmitter sends XOFF/XON as receive buffer
  2444.                   bytes available crosses trip levels).
  2445.  
  2446.          Format:  int async_xuset(port);
  2447.                    ASYNC *port;       Pointer to ASYNC structure
  2448.  
  2449.          Example:
  2450.  
  2451.                   ASYNC *port;
  2452.  
  2453.                   rcode = async_xuset(port);
  2454.  
  2455.          Returns: Not zero if XON/XOFF protocol is being used on the
  2456.                   transmit side, zero if it is not.
  2457.  
  2458.          Remarks: This function is implemented as a macro.  See
  2459.                   async_xflow, async_xuser, async_xuse.
  2460.  
  2461.